package com.junmoo.www.gateway.filter;

import com.alibaba.fastjson.JSONObject;
import com.junmoo.www.entity.SysUser;
import com.junmoo.www.gateway.config.SecurityIgnoreUrl;
import com.junmoo.www.tool.JwtUtils;
import com.junmoo.www.tool.RespUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.CollectionUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author dpwang
 */
@Slf4j
@Component
public class TokenVerifyFilter implements GlobalFilter, Ordered {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SecurityIgnoreUrl securityIgnoreUrl;
    private AntPathMatcher antPathMatcher = new AntPathMatcher();
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("------网关tokenheng验证----------");
        // 如果未启用网关验证，则跳过
        if (CollectionUtils.isEmpty(securityIgnoreUrl.getIgnoreUrl())) {
            return chain.filter(exchange);
        }
        String path = exchange.getRequest().getURI().getPath();
        String requestUrl = exchange.getRequest().getURI().getRawPath();
        if (ignore(path) || ignore(requestUrl)) {
            return chain.filter(exchange);
        }
        // 验证token是否有效
        ServerHttpResponse resp = exchange.getResponse();
        if(!verify(exchange)){
            return RespUtil.writeMsg(resp,"token 非法 ！！！");
        }
        String access_token = JwtUtils.generateToken(JSONObject.toJSONString("admin"));
        resp.getHeaders().set("access_token",access_token);
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }

    private boolean ignore(String path) {
        return securityIgnoreUrl.getIgnoreUrl().stream()
                .map(url -> url.replace("/**", ""))
                .anyMatch(path::startsWith);
    }

    /**
     * 验证token
     * @param exchange
     * @return
     */
    private boolean verify(ServerWebExchange exchange){
        String requestTokenHeader = exchange.getRequest().getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
        if (requestTokenHeader == null || !requestTokenHeader.startsWith("Bearer ")) {
            return false;
        }
        String requestToken = requestTokenHeader.substring(7);
        SysUser user = JSONObject.parseObject(JwtUtils.getSubject(requestToken), SysUser.class);
        if(user==null) {
            return false;
        }
        String redis_refresh_token = (String)redisTemplate.opsForHash().get(user.getUsername(),"token");
        if(JwtUtils.isTokenExpired(requestToken) ){
            if(redis_refresh_token==null ){
                return false;
            }
        }
        if(redis_refresh_token==null ){
            String refresh_token = JwtUtils.generateToken(JSONObject.toJSONString(user),3*60*60L);
            Map<String,Object> map = new HashMap();
            map.put("token",refresh_token);
            map.put("user",user);
            map.put("role",new String[]{"admin"});
            map.put("auth",user.getAuthorities());
            redisTemplate.opsForHash().putAll(user.getUsername(),map);
            redisTemplate.expire(user.getUsername(),2, TimeUnit.HOURS);
        }
        return true;
    }
    private boolean authorize(ServerWebExchange exchange){

        return false;
    }


}
